<?php

declare(strict_types=1);

namespace App\Controller;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Service\FileinfoService;
use App\Service\FlyOrderService;
use App\Service\ProductService;
use App\Service\TalkRoomService;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\SocketIOServer\Annotation\Event;
use Hyperf\SocketIOServer\Annotation\SocketIONamespace;
use Hyperf\SocketIOServer\BaseNamespace;
use Hyperf\SocketIOServer\Socket;
use Hyperf\Utils\Codec\Json;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Rule;
use Psr\Http\Message\ServerRequestInterface;


/**
 * @SocketIONamespace("/notify")
 */
class WsNotifyController extends BaseNamespace
{

    /**
     * @Inject()
     * @var ValidatorFactoryInterface
     */
    protected $validationFactory;

    /**
     * @Inject
     * @var TalkRoomService
     */
    private $talkRoom;

    /**
     * 审核
     * @Inject
     * @var ProductService
     */
    private $productService;

    /**
     * @Inject
     * @var FileinfoService
     */
    private $fileinfoService;


    /**
     * @Inject
     * @var FlyOrderService
     */
    private $orderService;
    /**
     * @Inject
     * @var ServerRequestInterface
     */
    protected $srequest;

    /**
     * @Event("event")
     * @param string $data
     */
    public function onEvent(Socket $socket, $data)
    {
        // 应答
        return 'Event Received: ' . $data;
    }

    /**
     * @Event("join-room")
     * @param Socket $socket
     * @param string $data
     */
    public function onJoinRoom(Socket $socket, $data)
    {
        $data = json_decode($data,true);
        $socket->join($data['room_id']);
        $shop_id = 103;
        $user_id = '1491675056485150723';
        $room_info  = $this->talkRoom->get_room(intval($shop_id),intval($user_id));
        $room_info = $room_info->toArray();
        // 向房间内其他用户推送（不含当前用户）
        $socket->to($data['room_id'])->emit('event', $socket->getSid() . "has joined {$data['room_id']}");
        // 向房间内所有人广播（含当前用户）
        $this->emit('event', 'There are ' . count($socket->getAdapter()->clients($data['room_id'])) . " players in {$data['room_id']}");
    }

    /**
     * @Event("say")
     * @param string $data
     */
    public function onSay(Socket $socket, $data)
    {
        $data = Json::decode($data);
        $data['send_by'] =   $user_id = $data['link_id'];
        $validator  = $this->validationFactory->make(
            $data,
            [
                'product_id'=>[
                    Rule::requiredIf($data['log_type']==5)
                ],
                'log_type'=>'min:1|max:2',
                'type'=>'min:1|max:2',
            ],
        );
        if ($validator->fails()) {
            $data['code'] = 500;
            $data['msg'] = implode(',', $validator->errors()->all());
        }else{
            go(function () use($data){
                $this->talkRoom->create_log($data);
            });
            $data['code'] = 200;
            if($data['log_type']==2||$data['log_type']==3){
                //             查询文件详情
                $data['url']  =    $this->fileinfoService->getFileinfo([76],1);
            }elseif ($data['log_type']==4){
                //             查询订单详情
                $data['order_info']  =  $this->orderService->getDetails(intval($user_id),intval($data['order_id']));
            }elseif ($data['log_type']==5){
                //             查询商品详情
                $data['order_info']  =  $this->productService->info(intval($data['product_id']));
            }else{

            }
        }
        $this->emit('event', json_encode($data));

//        $this->to($data['room_id'])->emit('event', json_encode($data));
    }

    /**
     * 更新
     * @Event("ack")
     * @param string $data
     */
    public function onAck(Socket $socket, $data)
    {
        $data = Json::decode($data);
        $validator  = $this->validationFactory->make(
            $data,
            [
                'type'=>'required|integer|min:1|max:2',
                'room_id'=>[
                    'required',
                    'integer',
                    'min:1',
                    Rule::exists('fly_talk_room','id')
                ],
                'link_id'=>[
                    'required',
                    'integer',
                    'min:1',
                    Rule::exists('fly_talk_room_user','link_id')->where('type',$data['type'])
                ],
            ],
        );

        if ($validator->fails()) {
            throw new BusinessException(ErrorCode::SYSTEM_INVALID, implode(',', $validator->errors()->all()));
        }
        $room_id = $data['room_id']??1;
        if($this->talkRoom->check_user(intval($room_id),intval($data['link_id']),intval($data['type']))){
           $this->talkRoom->update_ack(intval($room_id),intval($data['link_id']),intval($data['type']));
        };


    }
}
